﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ModelORM;
using PdfSharp.Pdf;
using PdfSharp.Drawing;

namespace FakturowanieLib
{
    interface IFakturaSave
    {
        bool SaveInvoice(tbl_faktura toSave, SavePlace where);
    }

    interface IData<T,V>
    {
        List<T> GetData();
        List<V> GetData(int ID);
    }

    public enum SavePlace { HDD, DataBase };

    public class Fakturyzator:IFakturaSave, IData<tbl_faktura, tbl_felementy>
    {
        //DOSTEP DO DB
        private MagazynEntities me = new MagazynEntities();

        private static Fakturyzator fakturyzator = null;
        //METODA DAJACA DOSTEP DO OBIEKTU TYPU FAKTURYZATOR (PRYWATNY KONSTRUKTOR) - SINGLETON
        public static Fakturyzator GetInstance()
        {
            if (fakturyzator == null)
            {
                fakturyzator = new Fakturyzator();
            }
            return fakturyzator;
        }

        private Fakturyzator() { }
        //INTERFEJS IFAKTURASAVE I METODY POMOCNICZE
        public bool SaveInvoice(tbl_faktura toSave, SavePlace where)
        {

            if (where == SavePlace.HDD)
            {
                if (SaveToHDD(toSave, (from p in me.tbl_felementy where p.IDFaktury == toSave.ID select p).ToList(), toSave.Numer + "_" + toSave.Rok))
                {
                    return true;
                }
                return false;
            }
            else if (where == SavePlace.DataBase)
            {
                if (SaveToDB(toSave, (from p in me.tbl_felementy where p.IDFaktury == toSave.ID select p).ToList()))
                {
                    return true;
                }
                return false;
            }
            else return false;
        }

        private bool SaveToDB(tbl_faktura faktura, List<tbl_felementy> listaElementow)
        {
            try
            {
                try
                {
                    IQueryable<tbl_felementy> listToDelete = (from p in me.tbl_felementy where p.IDFaktury == faktura.ID select p);
                    foreach (tbl_felementy toDelete in listToDelete)
                    {
                        me.DeleteObject(toDelete);
                    }
                    me.SaveChanges();
                }
                catch { }
                try
                {
                    tbl_faktura fakturaFromDB = (from p in me.tbl_faktura where p.ID == faktura.ID select p).First();
                    fakturaFromDB = faktura;
                    me.SaveChanges();
                }
                catch
                {
                    me.tbl_faktura.AddObject(faktura);
                    me.SaveChanges();
                }
                foreach (tbl_felementy element in listaElementow)
                {
                    me.tbl_felementy.AddObject(element);
                }
                me.SaveChanges();
            }
            catch
            {
                return false;
            }
            return true;
        }

        private bool SaveToHDD(tbl_faktura faktura, List<tbl_felementy> listaElementow, string savePath)
        {
            try
            {
                PdfDocument pdf = new PdfDocument();
                PdfPage page = pdf.AddPage();
                XGraphics gfx = XGraphics.FromPdfPage(page);
                XFont xfont = new XFont("Verdana", 10.0);
                gfx.DrawLine(XPens.Black, 50.0, 30.0, 240.0, 30.0);
                gfx.DrawLine(XPens.Black, 240.0, 30.0, 240.0, 100.0);
                gfx.DrawLine(XPens.Black, 50.0, 100.0, 240.0, 100.0);
                gfx.DrawLine(XPens.Black, 50.0, 30.0, 50.0, 100.0);
                gfx.DrawString("Pieczęc firmy", new XFont("Verdana", 7.0), XBrushes.Black, 120.0, 90.0);
                gfx.DrawRectangle(XBrushes.Gray, 244.0, 30.0, 150.0, 40.0);
                gfx.DrawString("Faktura VAT", new XFont("Verdana", 12, XFontStyle.Bold), XBrushes.Black, 280.0, 55.0);
                gfx.DrawLine(XPens.Black, 244.0, 72.0, 394.0, 72.0);
                gfx.DrawLine(XPens.Black, 244.0, 72.0, 244.0, 100.0);
                gfx.DrawLine(XPens.Black, 394.0, 72.0, 394.0, 100.0);
                gfx.DrawLine(XPens.Black, 244.0, 100.0, 394.0, 100.0);
                gfx.DrawString(faktura.Data.ToShortDateString(), new XFont("Verdana", 10.0, XFontStyle.Bold), XBrushes.Black, 290.0, 85.0);
                gfx.DrawString("data wystawienia", new XFont("Verdana", 7.0), XBrushes.Black, 293.0, 95.0);
                gfx.DrawLine(XPens.Black, 398.0, 30.0, 540.0, 30.0);
                gfx.DrawLine(XPens.Black, 540.0, 30.0, 540.0, 60.0);
                gfx.DrawLine(XPens.Black, 398.0, 30.0, 398.0, 60.0);
                gfx.DrawLine(XPens.Black, 398.0, 60.0, 540.0, 60.0);
                gfx.DrawString("Nr " + faktura.Numer + "/" + faktura.Rok, new XFont("Verdana", 10.0), XBrushes.Black, 445.0, 48.0);
                gfx.DrawString("ORYGINAŁ", new XFont("Verdana", 20.0, XFontStyle.Bold), XBrushes.Black, 410.0, 90.0);
                gfx.DrawLine(XPens.Black, 290, 104.0, 290.0, 154.0);
                gfx.DrawLine(XPens.Black, 50.0, 104.0, 290, 104.0);
                gfx.DrawLine(XPens.Black, 50.0, 104.0, 50.0, 154.0);
                gfx.DrawLine(XPens.Black, 50.0, 154.0, 290, 154.0);
                gfx.DrawString("Sprzedawca: NaszSuperMagazyn Sp.z o.o.", new XFont("Verdana", 7.0), XBrushes.Black, 60.0, 125.0);
                gfx.DrawString("Adres: ul.Magazynowa 32, 03-212 Magazynów", new XFont("Verdana", 7.0), XBrushes.Black, 60.0, 140.0);

                gfx.DrawLine(XPens.Black, 295.0, 104.0, 540.0, 104.0);
                gfx.DrawLine(XPens.Black, 295.0, 154.0, 540.0, 154.0);
                gfx.DrawLine(XPens.Black, 540.0, 104.0, 540.0, 154.0);
                gfx.DrawLine(XPens.Black, 295.0, 104.0, 295.0, 154.0);

                gfx.DrawString("Nabywca: " + faktura.tbl_klienci.Nazwa, new XFont("Verdana", 7.0), XBrushes.Black, 305.0, 125.0);
                gfx.DrawString("Adres: " + faktura.tbl_klienci.Adres, new XFont("Verdana", 7.0), XBrushes.Black, 305.0, 140.0);
                gfx.DrawLine(XPens.Black, 50.0, 160.0, 540.0, 160.0);
                gfx.DrawLine(XPens.Black, 50.0, 170.0, 540.0, 170.0);
                for (int i = 0; i < listaElementow.Count; i++)
                {
                    gfx.DrawString(i.ToString(), new XFont("Verdana", 7.0), XBrushes.Black, 63.0 - Convert.ToDouble(i.ToString().Length * 4), 178.0 + Convert.ToDouble(i) * 10);
                    gfx.DrawLine(new XPen(XColors.Black, 0.5), 50.0, 181.0 + Convert.ToDouble(i) * 10, 540.0, 181.0 + Convert.ToDouble(i) * 10);
                    gfx.DrawString(listaElementow[i].CenaZakupu.ToString(), new XFont("Verdana", 7.0), XBrushes.Black, 500.0 - Convert.ToDouble(listaElementow[i].CenaZakupu.ToString().Length * 4), 178.0 + Convert.ToDouble(i) * 10);
                    gfx.DrawString(listaElementow[i].tbl_produkt.Nazwa, new XFont("Verdana", 7.0), XBrushes.Black, 400.0 - Convert.ToDouble(listaElementow[i].tbl_produkt.Nazwa.Length * 4), 178.0 + Convert.ToDouble(i) * 10);

                }
                gfx.DrawLine(XPens.Black, 50.0, 160.0, 50.0, 171.0 + Convert.ToDouble(listaElementow.Count) * 10);
                gfx.DrawLine(XPens.Black, 50.0, 171.0 + Convert.ToDouble(listaElementow.Count) * 10, 540.0, 171.0 + Convert.ToDouble(listaElementow.Count) * 10);
                gfx.DrawLine(XPens.Black, 540.0, 160, 540.0, 171.0 + Convert.ToDouble(listaElementow.Count + 2) * 10);
                gfx.DrawString("Lp.", new XFont("Verdana", 7.0, XFontStyle.Bold), XBrushes.Black, 55.0, 168.0);
                gfx.DrawString("Nazwa", new XFont("Verdana", 7.0, XFontStyle.Bold), XBrushes.Black, 75.0, 168.0);
                gfx.DrawString("Cena", new XFont("Verdana", 7.0, XFontStyle.Bold), XBrushes.Black, 440.0, 168.0);
                gfx.DrawLine(XPens.Black, 70.0, 160, 70.0, 171.0 + Convert.ToDouble(listaElementow.Count) * 10);
                gfx.DrawLine(XPens.Black, 435.0, 160, 435.0, 171.0 + Convert.ToDouble(listaElementow.Count + 2) * 10);

                gfx.DrawLine(XPens.Black, 435.0, 171.0 + Convert.ToDouble(listaElementow.Count + 1) * 10, 540.0, 171.0 + Convert.ToDouble(listaElementow.Count + 1) * 10);
                gfx.DrawLine(XPens.Black, 435.0, 171.0 + Convert.ToDouble(listaElementow.Count + 2) * 10, 540.0, 171.0 + Convert.ToDouble(listaElementow.Count + 2) * 10);
                gfx.DrawString("Suma", new XFont("Verdana", 7.0, XFontStyle.Bold), XBrushes.Black, 440.0, 178.0 + Convert.ToDouble(listaElementow.Count) * 10);
                gfx.DrawString(listaElementow.Count.ToString(), new XFont("Verdana", 7.0, XFontStyle.Bold), XBrushes.Black, 496.0 - Convert.ToDouble((from p in listaElementow select p.CenaZakupu).Sum().ToString().Length * 4), 178.0 + Convert.ToDouble(listaElementow.Count + 1) * 10);
                pdf.Save(savePath);
                return true;
            }
            catch
            {
                return false;
            }
        }
        //INTERFEJS IDATA
        public List<tbl_faktura> GetData()
        {
            try
            {
                return (from p in me.tbl_faktura select p).OrderByDescending(p => p.Data).ToList();
            }
            catch
            {
                return new List<tbl_faktura>();
            }
        }

        public List<tbl_felementy> GetData(int ID)
        {
            try
            {
                return (from p in me.tbl_felementy where p.IDFaktury == ID select p).OrderBy(p=>p.ID).ToList();
            }
            catch
            {
                return new List<tbl_felementy>();
            }
        }
    }
}
